import {IHooksOptions} from '@/hooks/interface'
import {onMounted} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import {deleted, get} from "@/utils/request";
import {AxiosPromise} from "@/types/common";

export const useCrud = <T>(options: IHooksOptions<T>) => {
    // 设置默认参数
    const defaultOptions: IHooksOptions<T> = {
        createdIsNeed: true,
        dataListUrl: '',
        isPage: true,
        deleteUrl: '',
        primaryKey: 'id',
        exportUrl: '',
        queryForm: {},
        dataList: [] as T[],
        order: '',
        asc: false,
        pageNum: 1,
        pageSize: 10,
        total: 0,
        pageSizes: [1, 10, 20, 50, 100, 200],
        dataListLoading: false,
        dataListSelections: []
    }

    // 合并默认参数
    const mergeDefaultOptions = (options: any, props: any): IHooksOptions<T> => {
        for (const key in options) {
            if (!Object.getOwnPropertyDescriptor(props, key)) {
                props[key] = options[key]
            }
        }
        return props
    }

    // 覆盖默认值
    const state = mergeDefaultOptions(defaultOptions, options)

    // 页面挂载成功
    onMounted(() => {
        // 如果需要加载数据则加载
        if (state.createdIsNeed) {
            query()
        }
    })

    // 查询
    const query = () => {
        // 数据列表url不为空则加载
        if (!state.dataListUrl) return
        // 显示进度条
        state.dataListLoading = true
        // 获取数据
        get(state.dataListUrl,
            {
                order: state.order,
                asc: state.asc,
                pageNum: state.isPage ? state.pageNum : null,
                pageSize: state.isPage ? state.pageSize : null,
                ...state.queryForm
            }
        ).then((res: any) => {
            state.dataList = state.isPage ? res.data.list : res.data
            state.total = state.isPage ? Number(res.data.total) : 0
        }).finally(() => state.dataListLoading = false)
    }

    // 获取数据列表
    const getDataList = () => {
        state.pageNum = 1
        query()
    }

    // 页面数据改变
    const sizeChangeHandle = (val: number) => {
        state.pageNum = 1
        state.pageSize = val
        query()
    }

    // 当前页改变
    const currentChangeHandle = (val: number) => {
        state.pageNum = val
        query()
    }

    // 多选
    const selectionChangeHandle = (selections: any[]) => {
        state.dataListSelections = selections.map((item: any) => state.primaryKey && item[state.primaryKey])
    }

    // 排序
    const sortChangeHandle = (data: any) => {
        const {prop, order} = data

        if (prop && order) {
            state.order = prop
            state.asc = order === 'ascending'
        } else {
            state.order = ''
        }

        query()
    }

    // 删除
    const deleteHandle = (key: number | string) => {
        if (!state.deleteUrl) {
            return
        }

        ElMessageBox.confirm('确定进行删除操作?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
        })
            .then(() => {
                deleteWithKey(state.deleteUrl!!, key).then(res => {
                    if (res.data) {
                        ElMessage.success('删除成功')
                        query()
                    } else {
                        ElMessage.error(res.msg)
                    }
                })
            })
            .catch(() => {
            })
    }

    // 批量删除
    const deleteBatchHandle = (key?: number | string) => {
        let data: any[] = []
        if (key) {
            data = [key]
        } else {
            data = state.dataListSelections ? state.dataListSelections : []

            if (data.length === 0) {
                ElMessage.warning('请选择删除记录')
                return
            }
        }

        ElMessageBox.confirm('确定进行删除操作?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
        })
            .then(() => {
                if (state.deleteUrl) {
                    deleteByIds(state.deleteUrl, data).then(res => {
                        if (res.data) {
                            ElMessage.success('删除成功')
                            query()
                        } else {
                            ElMessage.error(res.msg)
                        }
                    })
                }
            })
            .catch(() => {
            })
    }

    /**
     * 根据 ID 删除
     * @param url 链接
     * @param arr ID 数组
     */
    const deleteByIds = (url: string, arr: number[]): AxiosPromise<boolean> => {
        return deleted(url, {ids: arr.join(",")});
    }

    /**
     * 根据 key 删除
     * @param url 链接
     * @param key 键
     */
    const deleteWithKey = (url: string, key: number | string): AxiosPromise<boolean> => {
        return deleted(state.deleteUrl + '/' + key);
    }

    return {
        getDataList,
        sizeChangeHandle,
        currentChangeHandle,
        selectionChangeHandle,
        sortChangeHandle,
        deleteHandle,
        deleteBatchHandle
    }
}


